allow filter aliases (groups)

Andrew Cantino 11 years ago
parent
commit
a2486b6785
2 changed files with 67 additions and 18 deletions
  1. 29 11
      app/models/agents/twitter_stream_agent.rb
  2. 38 7
      spec/models/agents/twitter_stream_agent_spec.rb

+ 29 - 11
app/models/agents/twitter_stream_agent.rb

@@ -9,6 +9,8 @@ module Agents
9 9
       You must provide an oAuth `consumer_key`, `consumer_secret`, `oauth_token`, and `oauth_token_secret`, as well as an array of `filters`.  Multiple words in a filter
10 10
       must all show up in a tweet, but are independent of order.
11 11
 
12
+      If you provide an array instead of a filter, the first entry will be considered primary and any additional values will be treated as aliases.
13
+
12 14
       To get oAuth credentials for Twitter, [follow these instructions](https://github.com/cantino/huginn/wiki/Getting-a-twitter-oauth-token).
13 15
 
14 16
       Set `expected_update_period_in_days` to the maximum amount of time that you'd expect to pass between Events being created by this Agent.
@@ -76,16 +78,20 @@ module Agents
76 78
     end
77 79
 
78 80
     def process_tweet(filter, status)
79
-      if options[:generate] == "counts"
80
-        # Avoid memory pollution by reloading the Agent.
81
-        agent = Agent.find(id)
82
-        agent.memory[:filter_counts] ||= {}
83
-        agent.memory[:filter_counts][filter.to_sym] ||= 0
84
-        agent.memory[:filter_counts][filter.to_sym] += 1
85
-        remove_unused_keys!(agent, :filter_counts)
86
-        agent.save!
87
-      else
88
-        create_event :payload => status.merge(:filter => filter.to_s)
81
+      filter = lookup_filter(filter)
82
+
83
+      if filter
84
+        if options[:generate] == "counts"
85
+          # Avoid memory pollution by reloading the Agent.
86
+          agent = Agent.find(id)
87
+          agent.memory[:filter_counts] ||= {}
88
+          agent.memory[:filter_counts][filter.to_sym] ||= 0
89
+          agent.memory[:filter_counts][filter.to_sym] += 1
90
+          remove_unused_keys!(agent, :filter_counts)
91
+          agent.save!
92
+        else
93
+          create_event :payload => status.merge(:filter => filter.to_s)
94
+        end
89 95
       end
90 96
     end
91 97
 
@@ -100,9 +106,21 @@ module Agents
100 106
 
101 107
     protected
102 108
 
109
+    def lookup_filter(filter)
110
+      options[:filters].each do |known_filter|
111
+        if known_filter == filter
112
+          return filter
113
+        elsif known_filter.is_a?(Array)
114
+          if known_filter.include?(filter)
115
+            return known_filter.first
116
+          end
117
+        end
118
+      end
119
+    end
120
+
103 121
     def remove_unused_keys!(agent, base)
104 122
       if agent.memory[base]
105
-        (agent.memory[base].keys - agent.options[:filters].map(&:to_sym)).each do |removed_key|
123
+        (agent.memory[base].keys - agent.options[:filters].map {|f| f.is_a?(Array) ? f.first.to_sym : f.to_sym }).each do |removed_key|
106 124
           agent.memory[base].delete(removed_key)
107 125
         end
108 126
       end

+ 38 - 7
spec/models/agents/twitter_stream_agent_spec.rb

@@ -24,19 +24,35 @@ describe Agents::TwitterStreamAgent do
24 24
       end
25 25
 
26 26
       it 'records counts' do
27
-        @agent.process_tweet(:keyword1, {:text => "something", :user => {:name => "Mr. Someone"}})
28
-        @agent.process_tweet(:keyword2, {:text => "something", :user => {:name => "Mr. Someone"}})
29
-        @agent.process_tweet(:keyword1, {:text => "something", :user => {:name => "Mr. Someone"}})
27
+        @agent.process_tweet('keyword1', {:text => "something", :user => {:name => "Mr. Someone"}})
28
+        @agent.process_tweet('keyword2', {:text => "something", :user => {:name => "Mr. Someone"}})
29
+        @agent.process_tweet('keyword1', {:text => "something", :user => {:name => "Mr. Someone"}})
30 30
 
31 31
         @agent.reload
32 32
         @agent.memory[:filter_counts][:keyword1].should == 2
33 33
         @agent.memory[:filter_counts][:keyword2].should == 1
34 34
       end
35 35
 
36
+      it 'records counts for keyword sets as well' do
37
+        @agent.options[:filters][0] = %w[keyword1-1 keyword1-2 keyword1-3]
38
+        @agent.save!
39
+
40
+        @agent.process_tweet('keyword2', {:text => "something", :user => {:name => "Mr. Someone"}})
41
+        @agent.process_tweet('keyword2', {:text => "something", :user => {:name => "Mr. Someone"}})
42
+        @agent.process_tweet('keyword1-1', {:text => "something", :user => {:name => "Mr. Someone"}})
43
+        @agent.process_tweet('keyword1-2', {:text => "something", :user => {:name => "Mr. Someone"}})
44
+        @agent.process_tweet('keyword1-3', {:text => "something", :user => {:name => "Mr. Someone"}})
45
+        @agent.process_tweet('keyword1-1', {:text => "something", :user => {:name => "Mr. Someone"}})
46
+
47
+        @agent.reload
48
+        @agent.memory[:filter_counts][:'keyword1-1'].should == 4 # it stores on the first keyword
49
+        @agent.memory[:filter_counts][:keyword2].should == 2
50
+      end
51
+
36 52
       it 'removes unused keys' do
37 53
         @agent.memory[:filter_counts] = {:keyword1 => 2, :keyword2 => 3, :keyword3 => 4}
38 54
         @agent.save!
39
-        @agent.process_tweet(:keyword1, {:text => "something", :user => {:name => "Mr. Someone"}})
55
+        @agent.process_tweet('keyword1', {:text => "something", :user => {:name => "Mr. Someone"}})
40 56
         @agent.reload.memory[:filter_counts].should == {:keyword1 => 3, :keyword2 => 3}
41 57
       end
42 58
     end
@@ -53,6 +69,21 @@ describe Agents::TwitterStreamAgent do
53 69
           :user => {:name => "Mr. Someone"}
54 70
         }
55 71
       end
72
+
73
+      it 'handles keyword sets too' do
74
+        @agent.options[:filters][0] = %w[keyword1-1 keyword1-2 keyword1-3]
75
+        @agent.save!
76
+
77
+        lambda {
78
+          @agent.process_tweet('keyword1-2', {:text => "something", :user => {:name => "Mr. Someone"}})
79
+        }.should change { @agent.events.count }.by(1)
80
+
81
+        @agent.events.last.payload.should == {
82
+          :filter => 'keyword1-1',
83
+          :text => "something",
84
+          :user => {:name => "Mr. Someone"}
85
+        }
86
+      end
56 87
     end
57 88
   end
58 89
 
@@ -64,9 +95,9 @@ describe Agents::TwitterStreamAgent do
64 95
       end
65 96
 
66 97
       it 'emits events' do
67
-        @agent.process_tweet(:keyword1, {:text => "something", :user => {:name => "Mr. Someone"}})
68
-        @agent.process_tweet(:keyword2, {:text => "something", :user => {:name => "Mr. Someone"}})
69
-        @agent.process_tweet(:keyword1, {:text => "something", :user => {:name => "Mr. Someone"}})
98
+        @agent.process_tweet('keyword1', {:text => "something", :user => {:name => "Mr. Someone"}})
99
+        @agent.process_tweet('keyword2', {:text => "something", :user => {:name => "Mr. Someone"}})
100
+        @agent.process_tweet('keyword1', {:text => "something", :user => {:name => "Mr. Someone"}})
70 101
 
71 102
         lambda {
72 103
           @agent.reload.check